package log

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/golang/glog"
)

const default_log_dir = "~/logs"

type FileLog struct {
	options Options
}

func (self *FileLog) Init(options ...Option) {
	for _, op := range options {
		op(&self.options)
	}

	if self.options.logBatchSize <= 0 {
		self.options.logBatchSize = 1024 * 1024 * 50
	}
	glog.MaxSize = self.options.logBatchSize

	err := flag.Set("v", fmt.Sprintf("%d", self.options.logLevel))
	if err != nil {
		panic(err)
	}

	if self.options.logDir == "" {
		self.options.logDir = default_log_dir
		f, _ := os.Stat(self.options.logDir)
		if f == nil {
			err = os.MkdirAll(self.options.logDir, os.ModePerm)
			if err != nil {
				panic(err)
			}
		}
	}
	err = flag.Set("log_dir", self.options.logDir)
	if err != nil {
		panic(err)
	}

	flag.Parse()

	go func() {
		c := time.NewTicker(time.Second * 5).C
		for {
			<-c
			self.Flush()
		}
	}()
}

func (self *FileLog) infoProc(module string, format string, args ...interface{}) string {
	var info string
	if len(args) == 0 {
		if module == "" {
			info = format
		} else {
			info = module + "; " + format
		}
	} else {
		if module == "" {
			info = fmt.Sprintf(format, args...)
		} else {
			info = fmt.Sprintf(module+"; "+format, args...)
		}
	}

	return info
}

func (self *FileLog) Record(module string, format string, args ...interface{}) {
	info := self.infoProc(module, format, args...)
	glog.InfoDepth(1, info)
}

func (self *FileLog) Info(module string, level Level, format string, args ...interface{}) {
	if level < I {
		level = I
	} else if level > LvMax {
		level = LvMax
	}
	if glog.V(glog.Level(level)) {
		// 若depth为0或是直接glog.Info的话，log中只会记录[....log.go 53] xxxxxx
		// 而我们需要调用log的那个地方[....AAA.go 99] xxxxxx
		// 所以Depth要+1
		info := self.infoProc(module, format, args...)
		glog.InfoDepth(1, info)
		if self.options.showOnConsole {
			fmt.Println(info)
		}
	}
}

func (self *FileLog) Warn(module string, format string, args ...interface{}) {
	if glog.V(glog.Level(W)) {
		warning := self.infoProc(module, format, args...)
		glog.WarningDepth(1, warning)
		if self.options.showOnConsole {
			fmt.Println(warning)
		}
	}
}

func (self *FileLog) Error(module string, format string, args ...interface{}) {
	if glog.V(glog.Level(E)) {
		errInfo := self.infoProc(module, format, args...)
		glog.ErrorDepth(1, errInfo)
		if self.options.showOnConsole {
			fmt.Println(errInfo)
		}
	}
}
func (self *FileLog) Panic(module string, format string, args ...interface{}) {
	errInfo := self.infoProc(module, format, args...)
	glog.ErrorDepth(1, errInfo)
	panic(errors.New(errInfo))
}

func (self *FileLog) Flush() {
	glog.Flush()
}
